本题将会给出
条地址信息,确切数字未知,您需要一直读取至文件结尾;您也可以参考 牛客网在线判题系统使用帮助 获得更多的使用帮助。每条地址信息描述如下:
每行输入一个
形式的 IP 地址和一个
形式的子网掩码,中间用波浪线(
)分隔。保证
要么为空,要么是一个
到
间的整数。
在一行上输出七个整数,分别代表 A 类地址数、B 类地址数、C 类地址数、D 类地址数、E 类地址数、错误 IP 或错误子网掩码数、私有 IP 数。
10.70.44.68~1.1.1.5 1.0.0.1~255.0.0.0 192.168.0.2~255.255.255.0 19..0.~255.255.255.0
1 0 1 0 0 2 1
在这个样例中:
第一条地址信息:掩码非法;
第二条地址信息:IP 格式和掩码均合法,属于 A 类;
第三条地址信息:IP 格式和掩码均合法,属于 C 类私有地址;
第四条地址信息:IP 格式非法。
统计得到
个 A 类,
个 B 类,
个 C 类,
个 D 类,
个 E 类,
个错误条目,
个私有地址。
0.201.56.50~255.255.255.0 127.201.56.50~255.255.111.255
0 0 0 0 0 0 0
在这个样例中,两条地址信息均属于上方提示中提到的特殊 IP 地址,不需要处理,直接跳过。特别需要注意地,第二条地址的子网掩码是非法的。但是因为该条为特殊 IP 地址,此优先级更高,所以不进入统计。
本题已于下方时间节点更新,请注意题解时效性:
1. 2025-05-30 更新题面。
2. 2024-12-16 更新题面。
import sys # 五类IP def judge_1(x): type_ip = None data = [] for num in x: if num == '': type_ip = False return type_ip else: num = int(num) data.append(num) if 1 <= data[0] <= 126 and 0 <= data[1] <= 255 and 0 <= data[2] <= 255 and 0 <= data[3] <= 255: type_ip = 'A' elif 128 <= data[0] <= 191 and 0 <= data[1] <= 255 and 0 <= data[2] <= 255 and 0 <= data[3] <= 255: type_ip = 'B' elif 192 <= data[0] <= 223 and 0 <= data[1] <= 255 and 0 <= data[2] <= 255 and 0 <= data[3] <= 255: type_ip = 'C' elif 224 <= data[0] <= 239 and 0 <= data[1] <= 255 and 0 <= data[2] <= 255 and 0 <= data[3] <= 255: type_ip = 'D' elif 240 <= data[0] <= 255 and 0 <= data[1] <= 255 and 0 <= data[2] <= 255 and 0 <= data[3] <= 255: type_ip = 'E' return type_ip # 私有IP def judge_2(x): data = [] type_ip = None for num in x: if num == '': type_ip = False return type_ip else: num = int(num) data.append(num) if data[0] == 10 and 0 <= data[1] <= 255 and 0 <= data[2] <= 255 and 0 <= data[3] <= 255: type_ip = True elif data[0] == 172 and 16 <= data[1] <= 31 and 0 <= data[2] <= 255 and 0 <= data[3] <= 255: type_ip = True elif data[0] == 192 and data[1] == 168 and 0 <= data[2] <= 255 and 0 <= data[3] <= 255: type_ip = True return type_ip # 二进制转换 def bin_convert(data): bin_num = [] if data == 0: bin_num.append('0') else: while True: if data // 2 > 0: if data % 2 > 0: bin_num.append('1') data //= 2 elif data % 2 == 0: bin_num.append('0') data //= 2 elif data // 2 == 0: bin_num.append('1') break # 要补0,如果位数小于8的话 # 补零的个数: n = 8 - len(bin_num) # 这里转换是列表,如果不转换为字符串,后面会和子码里面转换为字符串冲突 bin_num = ''.join(bin_num) bin_num = bin_num + n * '0' bin_num = bin_num[::-1] return bin_num # 子网掩码判定 def judge_mask(x): data = [] result = None for num in x: if num == '': result = False break else: num = int(num) data.append(num) mask = [] # 全为0或者1的都是非法的 i = 0 while i <= 3: mask.append(bin_convert(data[i])) i += 1 mask = "".join(mask) # 转换为字符串后,可以以0来分割 mask = mask.split('0') if len(mask) == 1: result = False return result conunt = 0 for element in mask: if element != '': conunt += 1 # 如果分割后的非空元素个数大于1个,说明后面还有1 if conunt > 1: result = False # 如果非空元素等于0,说明全是1 elif conunt == 0: result = False else: result = True return result # 特殊IP判定 def judge_specialip(x): type_ip = None data = [] for num in x: if num == '': type_ip = False return type_ip else: num = int(num) data.append(num) data[0] = int(data[0]) if data[0] == 0&nbs***bsp;data[0] == 127: type_ip = True return type_ip type_A = 0 type_B = 0 type_C = 0 type_D = 0 type_E = 0 type_error = 0 type_private = 0 ip_info = [] for line in sys.stdin: p = line.split() ip_ipmask = p[0].split('~') ip = ip_ipmask[0].split('.') ipmask = ip_ipmask[1].split('.') if len(ip) != 4&nbs***bsp;len(ipmask) != 4: continue # 特殊ip优先级最高,先判定 else: if judge_specialip(ip): pass else: if judge_mask(ipmask): if judge_2(ip): type_private += 1 if judge_1(ip) == 'A': type_A += 1 elif judge_1(ip) == 'B': type_B += 1 elif judge_1(ip) == 'C': type_C += 1 elif judge_1(ip) == 'A': type_A += 1 elif judge_1(ip) == 'B': type_B += 1 elif judge_1(ip) == 'C': type_C += 1 elif judge_1(ip) == 'D': type_D += 1 elif judge_1(ip) == 'E': type_E += 1 else: type_error += 1 print(f"{type_A} {type_B} {type_C} {type_D} {type_E} {type_error} {type_private}")
10.70.44.68~255.254.255.0的子网掩码非法,19..0.~255.255.255.0的IP地址非法,所以错误IP地址或错误掩码的计数为2; 1.0.0.1~255.0.0.0是无误的A类地址; 192.168.0.2~255.255.255.0是无误的C类地址且是私有IP; 127.69.131.137~255.70.255.255 计数忽略 所以最终的结果为1 0 1 0 0 2 1第二个例子却没有因为 0 或 127 忽略错误计数, 如按例子1的做法, 这里应该为0, 但是答案却为2, 所以对了题1就没法对题2, 对了题2就没法对题1啊!
0.201.56.50~255.255.111.255 127.201.56.50~255.255.111.255
0 0 0 0 0 2 0
类似于【0.*.*.*】和【127.*.*.*】的IP地址不属于上述输入的任意一类,也不属于不合法ip地址,计数时请忽略
ip_lst = [] mask_lst = [] res = [0]*7 def is_valid(addr, mask=False): if mask and (addr == '255.255.255.255'&nbs***bsp;addr == '0.0.0.0'): return False bin_addr = '' segs = addr.split('.') for i in range(len(segs)): if not segs[i]: return False segs[i] = int(segs[i]) if segs[i] < 0&nbs***bsp;segs[i] > 255: return False if mask: bin_addr += '{:0>8}'.format(bin(segs[i])[2:]) if bin_addr: inx_0 = bin_addr.find('0') inx_1 = bin_addr.rfind('1') if inx_0 - inx_1 == 1: return True else: return False return True while True: try: ip, mask = input().split('~') segs = list(map(int, ip.split('.'))) # 跳过0.*.*.*和127.*.*.*类地址 if segs[0] == 0&nbs***bsp;segs[0] == 127: continue if not is_valid(ip)&nbs***bsp;not is_valid(mask, True): res[-2] += 1 else: # 判断A类地址和私网1 if 1 <= segs[0] <= 126: if segs[0] == 10: res[-1] += 1 res[0] += 1 # 判断B类地址和私网2 elif 128 <= segs[0] <= 191: if segs[0] == 172 and (16 <= segs[1] <= 31): res[-1] += 1 res[1] += 1 # 判断C类地址和私网3 elif 192 <= segs[0] <= 223: if segs[0] == 192 and segs[1] == 168: res[-1] += 1 res[2] += 1 # 判断D类地址 elif 224 <= segs[0] <= 239: res[3] += 1 # 判断E类地址 elif 240 <= segs[0] <= 255: res[4] += 1 except: break print(' '.join(map(str, res))) """ 注意 0.*.*.*和127.*.*.*类地址不参与分类判断,要最先排除,否则可能影响子网掩码不合法数量异常 """
import sys address = [] mask = [] A = 0 B = 0 C = 0 D = 0 E = 0 error = 0 private = 0 for line in sys.stdin: a = line.split("~") address.append(a[0]) mask.append(a[1][:-1]) # 判断掩码是否合法 def is_valid_mask(m): x = ["255","254","252","248","240","224","192", "128","0"] m1 = m.split(".") n = 0 sum1 = 0 # 四个码的和 for code in m1: sum1 += int(code) if n == 1 and code != "0": return False if code != "255": if code in x: n = 1 else: return False if sum1 == 0&nbs***bsp;sum1 == 255 * 4: return False return True # 判断IP地址是否合法 def is_valid_address(a): try: result = False for i in a.split("."): if int(i)>=0 and int(i)<=255: result = True return result except: return False # 判断IP地址是否为私有IP def is_private_IP(ip): a = ip.split(".") if a[0] == "10": return True if a[0] == "172": if int(a[1]) >= 16 and int(a[1]) <= 31: return True if a[0] == "192": if int(a[1]) == 168: return True return False for i in range(len(address)): a = address[i].split(".") if a[0] == "0"&nbs***bsp;a[0] == "127": continue if is_valid_address(address[i]): if is_valid_mask(mask[i]): # a = address[i].split(".") if int(a[0]) >= 1 and int(a[0]) <= 126: A += 1 if int(a[0]) >= 128 and int(a[0]) <= 191: B += 1 if int(a[0]) >= 192 and int(a[0]) <= 223: C += 1 if int(a[0]) >= 224 and int(a[0]) <= 239: D += 1 if int(a[0]) >= 240 and int(a[0]) <= 255: E += 1 if is_private_IP(address[i]): private += 1 else: error += 1 else: error += 1 print(A,B,C,D,E,error,private)
['255', '110', '255', '255'] 1111111111011101111111111111111 ['255', '255', '58', '255'] 111111111111111111101011111111 ['255', '255', '154', '0'] 1111111111111111100110100 ['255', '255', '255', '100'] 1111111111111111111111111100100 ['255', '255', '111', '255'] 1111111111111111110111111111111 ['255', '86', '0', '0'] 11111111101011000 ['255', '255', '255', '139'] 11111111111111111111111110001011 ['255', '255', '90', '255'] 1111111111111111101101011111111 ['255', '153', '0', '0'] 111111111001100100 ['255', '255', '255', '255'] 11111111111111111111111111111111 ['255', '0', '15', '0'] 11111111011110 ['255', '255 ', '255', '255'] 11111111111111111111111111111111 ['255', '0', '0', '226'] 111111110011100010 ['255', '255', '74', '255'] 1111111111111111100101011111111
import sys def judge_ip(ip_list:list[str])->bool: flag = False if len(ip_list) == 4: if ip_list[0] in [str(i) for i in range(1,256)] and ip_list[0] != "127": for i in range(1,4): if ip_list[i] in [str(i) for i in range(256)]: flag = True return flag def get_ip_class(ip_list:list[str])->str: type = "" if ip_list[0] in [str(i) for i in range(1,127)]: type = "A" if ip_list[0] in [str(i) for i in range(128,192)]: type = "B" if ip_list[0] in [str(i) for i in range(192,224)]: type = "C" if ip_list[0] in [str(i) for i in range(224,240)]: type = "D" if ip_list[0] in [str(i) for i in range(240,256)]: type = "E" return type def judge_personal_ip(ip_list:list[str])->bool: flag = False if ip_list[0] == "10": flag = True elif ip_list[0] == "172" and ip_list[1] in [str(i) for i in range(16,32)]: flag = True elif ip_list[0] == "192" and ip_list[1] == "168": flag = True return flag def judge_mask(mask_list:list[str])->bool: flag = False sum_temp = 0 legal_num = [] for i in range(7,-1,-1): sum_temp += pow(2,i) legal_num.append(str(sum_temp)) if len(mask_list) == 4: if mask_list[0] in legal_num and mask_list[1]=="0" and mask_list[2]=="0" and mask_list[3]=="0": flag = True if mask_list[0]=="255" and mask_list[1] in legal_num and mask_list[2]=="0" and mask_list[3]=="0": flag = True if mask_list[0]=="255" and mask_list[1]=="255" and mask_list[2] in legal_num and mask_list[3]=="0": flag = True if mask_list[0]=="255" and mask_list[1]=="255" and mask_list[2]=="255" and mask_list[3] in legal_num: flag = True if mask_list[0]=="255" and mask_list[1]=="255" and mask_list[2]=="255" and mask_list[3]=="255": flag = False if mask_list[0]=="0" and mask_list[1]=="0" and mask_list[2]=="0" and mask_list[3]=="0": flag = False return flag A,B,C,D,E,wrong,personal = 0,0,0,0,0,0,0 for line in sys.stdin: # print(line) line = line.rstrip('\n') ip,mask = line.split('~') ip_list = [i for i in ip.strip(".").split(".") if i != ""] mask_list = [i for i in mask.strip(".").split(".") if i != ""] # print(ip_list) # print(mask_list) if ip_list[0] in ["0", "127"]: continue else: if judge_ip(ip_list) and judge_mask(mask_list): if judge_personal_ip(ip_list): personal += 1 class_ = get_ip_class(ip_list) if class_ == "A": A += 1 if class_ == "B": B += 1 if class_ == "C": C += 1 if class_ == "D": D += 1 if class_ == "E": E += 1 else: wrong += 1 print("{} {} {} {} {} {} {}".format(A,B,C,D,E,wrong,personal)) # 重点1: # 使用 for line in sys.stdin 读进来的line会包括最后一个回车字符'\n',进行后续计算之前一定要记得先使用rstrip('\n')方法去掉 # 重点2: # 对于ip = "19..0." 这种特殊字符串,单纯使用ip.split('.')得到的ip_list = ['19', '', '0', ''] 会包含空字符串, # 如果不想包含空字符串,,需要使用ip_list = [part for part in ip.split('.') if part != ''],结果ip_list = ['19', '0']
import sys a,b,c,d,e,err,pri = 0,0,0,0,0,0,0 ipt = [] for line in sys.stdin: temp = line.split()[0] ipt.append(temp) for row in ipt: ips = row.split('~')[0].split('.') ym = row.split('~')[1].split('.') if ips[0]=='0'&nbs***bsp;ips[0]=='127' : continue legal = True for i in ips: if not str(i).isdigit(): legal = False break if not 0<=int(i)<=255: legal = False break yms = '' for j in ym: yms += str(bin(int(j))) yms = yms.replace('0b','') if ('10' not in yms)&nbs***bsp;('01' in yms): legal = False if not legal: err += 1 continue if 1<=int(ips[0])<=127: a += 1 if 128<=int(ips[0])<=191: b += 1 if 192<=int(ips[0])<=223: c += 1 if 224<=int(ips[0])<=239: d += 1 if 240<=int(ips[0])<=255: e += 1 if int(ips[0])==10: pri += 1 if int(ips[0])==172 and 16<=int(ips[1])<=31: pri += 1 if int(ips[0])==192 and int(ips[1])==168: pri += 1 print(a,b,c,d,e,err,pri)
# 当ip为0或127开头,则即使子网掩码是错误的,也忽略不计数 import sys input1 = [i.strip() for i in sys.stdin] def isR(item,type): tmpData = item.split('.') if len(tmpData) != 4: return False else: if type=='ip': res = [] for i in tmpData: if i =='': res.append(False) elif 0<=int(i)<=255: res.append(True) else: res.append(False) res = False if False in res else True return res elif type=='subCode': subCode_bin = get_ip_bin(item) if '1' not in subCode_bin: return False elif '0' not in subCode_bin: return False else: if subCode_bin.count('10')==1: a,b = subCode_bin.split('10') if '0' not in a and '1' not in b: return True else: return False else: return False def get_ip_bin(item): res = [bin(int(i))[2:] for i in item.split('.')] for i in range(4): res[i] = '0'*(8-len(res[i]))+res[i] return ''.join(res) def isIn(ipStart,ipEnd,res_ip): if int(get_ip_bin(ipStart)) <= int(res_ip) <= int(get_ip_bin(ipEnd)): return True else: return False countRes = {'A':0,'B':0,'C':0,'D':0,'E':0,'***t_ip':0,'private':0} for i in range(len(input1)): ip,subCode = input1[i].split('~') tmp = ip.split('.') if tmp[0]=='0'&nbs***bsp;tmp[0]=='127': continue if isR(ip,'ip') and isR(subCode,'subCode'): ip_bin = get_ip_bin(ip) subCode_bin = get_ip_bin(subCode) res_ip='' for j in range(32): if ip_bin[j] == '1' and subCode_bin[j] == '1': res_ip+='1' else: res_ip+='0' if isIn('1.0.0.0','126.255.255.255',res_ip): countRes['A']+=1 elif isIn('128.0.0.0','191.255.255.255',res_ip): countRes['B']+=1 elif isIn('192.0.0.0','223.255.255.255',res_ip): countRes['C']+=1 elif isIn('224.0.0.0','239.255.255.255',res_ip): countRes['D']+=1 elif isIn('240.0.0.0','255.255.255.255',res_ip): countRes['E']+=1 if isIn('10.0.0.0','10.255.255.255',res_ip)&nbs***bsp;isIn('172.16.0.0','172.31.255.255',res_ip)&nbs***bsp;isIn('192.168.0.0','192.168.255.255',res_ip): countRes['private']+=1 else: countRes['***t_ip']+=1 print(*countRes.values(),sep=' ')